﻿using System;
using Airborne.ScrumPoker.Model.Cards;
using Airborne.ScrumPoker.Module.Developer.Views;
using Airborne.ScrumPoker.Module.Events;
using Microsoft.Practices.Composite.Events;
using Microsoft.Practices.Composite.Regions;
using Microsoft.Practices.Composite.Wpf.Events;
using Microsoft.Practices.Unity;

namespace Airborne.ScrumPoker.Module.Developer.Controllers
{
    public class CardsController : ICardsController
    {

        #region Constructor
        public CardsController(IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer container)
        {
            RegionManager = regionManager;
            EventAggregator = eventAggregator;
            Container = container;
        }
        #endregion

        #region Properties
        private IRegionManager RegionManager { get; set; }
        private IEventAggregator EventAggregator { get; set; }
        private IUnityContainer Container { get; set; }
        private ICardsView CardsView { get; set; }
        #endregion


        public void Run()
        {
            CardsView = Container.Resolve<ICardsView>();

            SubscribeToEvents();

            RegionManager.Regions[RegionNames.CardsRegion].AddAndActivate(CardsView);
        }

        private void SubscribeToEvents()
        {
            CardsView.CardSelected += new EventHandler<Airborne.ScrumPoker.Module.Events.GenericEventArgs<ICard>>(CardSelected);

            EventAggregator.GetEvent<GenericEvent<string>>().Subscribe(SubscribeClient, ThreadOption.UIThread, true, p => p.Topic == EventTopics.ClientSubscribed);
            EventAggregator.GetEvent<GenericEvent<int>>().Subscribe(TimerStarted, ThreadOption.UIThread, true, p => p.Topic == EventTopics.StartTimer);
            EventAggregator.GetEvent<GenericEvent<string>>().Subscribe(TimerEnded, ThreadOption.UIThread, true, p => p.Topic == EventTopics.StopTimer);
            EventAggregator.GetEvent<GenericEvent<string>>().Subscribe(ResetVote, ThreadOption.UIThread, true, p => p.Topic == EventTopics.ResetVote);
        }

        private void CardSelected(object sender, GenericEventArgs<ICard> e)
        {
            EventAggregator.GetEvent<GenericEvent<double>>().Publish(new EventParameters<double>(EventTopics.CastVote, e.Data.ActualValue));
        }

        private void TimerStarted(EventParameters<int> parameters)
        {
            CardsView.VotingEnabled = true;
        }

        private void TimerEnded(EventParameters<string> parameters)
        {
            CardsView.VotingEnabled = false;
        }

        private void ResetVote(EventParameters<string> parameters)
        {
            ReShuffleCards();
        }

        private void SubscribeClient(EventParameters<string> parameters)
        {
            ReShuffleCards();
        }

        private void ReShuffleCards()
        {
            CardsView.VotingEnabled = true;
            CardsView.SetSequence(CardFactory.CreateSequence());
        }
    }
}
